

/**
 * @author Carlos
 * @version 1.0
 * @created 09-oct-2013 05:23:50 p.m.
 */
using Imaginarium.team;
using GameEngine.utils.console;
using Imaginarium.stats;
using System;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using Imaginarium.items.equip;
using Imaginarium.effect;
namespace Imaginarium.battleSistem
{
    public class AttackCommand : BattleCommand
    {

        public AttackCommand(Character performer, Character target):
            base(performer,target)
        {
            this.type = BattleOption.BattleOptionEnum.Attack;
        }
        public override void startAnimation()
        {
            base.startAnimation();
            Performer.setAnimation(Performer.getAttackType()==Character.TypeOfAttack.melee? CodeParameters.MeleeAttackAnimationName:
                Performer.getAttackType()==Character.TypeOfAttack.range? CodeParameters.RangeAttackAnimationName:
                CodeParameters.MagicAttackAnimationName);
        }
        public override void execute()
        {
            base.execute();
            bool doesHit = calculateDoesHit();
            if (doesHit)
            {
                Target.receiveDamage(); //only prints
                DamageMaker damageMaker = getFinalDamage();
                damageMaker.doDamage();
                damagesDealt.Add(damageMaker);
                //Target.reciveSpecialStates(getSpecialStatesToTry());
            }
            else {
                Target.dodgedAttack();
                DamageMaker damageMaker = getMiss();
                damagesDealt.Add(damageMaker);
            }

            
        }

        

        private DamageMaker getFinalDamage() {
            DamageMaker bd = new DamageMaker();
            bd.Target = Target;
            bd.normalDamage= (Performer.stats.attk - Target.stats.def) < 0 ? 0 : Performer.stats.attk - Target.stats.def;
            if (Performer.getFinalStats().attElemental == null) return bd; 
            if (Target.getFinalStats().defElemental == null) Target.stats.defElemental = new Elemental();
            if (!Performer.stats.attElemental.isPercentage)
            {
                bd.earthDamage += (int)(Performer.getFinalStats().attElemental.earth   *   (StatsParameter.INITIAL_ELEMENTAL_DAMAGE + (Target.getFinalStats().defElemental.earth * -1)));
                bd.fireDamage  += (int)(Performer.getFinalStats().attElemental.fire    *   (StatsParameter.INITIAL_ELEMENTAL_DAMAGE + (Target.getFinalStats().defElemental.fire * -1)));
                bd.waterDamage += (int)(Performer.getFinalStats().attElemental.water   *   (StatsParameter.INITIAL_ELEMENTAL_DAMAGE + (Target.getFinalStats().defElemental.water * -1)));
                bd.windDamage  += (int)(Performer.getFinalStats().attElemental.wind    *   (StatsParameter.INITIAL_ELEMENTAL_DAMAGE + (Target.getFinalStats().defElemental.wind * -1)));
            }
            else {
                bd.earthDamage += (int)((Performer.getFinalStats().attk * Performer.getFinalStats().attElemental.earth / 100) * (StatsParameter.INITIAL_ELEMENTAL_DAMAGE + (Target.getFinalStats().defElemental.earth * -1)));
                bd.fireDamage += (int)((Performer.getFinalStats().attk * Performer.getFinalStats().attElemental.fire / 100) * (StatsParameter.INITIAL_ELEMENTAL_DAMAGE + (Target.getFinalStats().defElemental.fire * -1)));
                bd.waterDamage += (int)((Performer.getFinalStats().attk * Performer.getFinalStats().attElemental.water / 100) * (StatsParameter.INITIAL_ELEMENTAL_DAMAGE + (Target.getFinalStats().defElemental.water * -1)));
                bd.windDamage += (int)((Performer.getFinalStats().attk * Performer.getFinalStats().attElemental.wind / 100) * (StatsParameter.INITIAL_ELEMENTAL_DAMAGE + (Target.getFinalStats().defElemental.wind * -1)));
            }
            return bd;
        }

        private List<DetailSpecialState> getSpecialStatesToTry() {
            List<DetailSpecialState> dssList;
            if (Performer.currentEquipment == null || Performer.currentEquipment.getEquipedItemByPosition(Imaginarium.items.equip.EquipmentPosition.PrimaryHand) == null) return null;
            
            dssList = Performer.currentEquipment.getEquipedItemByPosition(Imaginarium.items.equip.EquipmentPosition.PrimaryHand).posibleStates;
            if (!((Weapon)Performer.currentEquipment.getEquipedItemByPosition(Imaginarium.items.equip.EquipmentPosition.PrimaryHand)).twoHanded) {
                if (dssList == null) dssList = new List<DetailSpecialState>();
                dssList.AddRange(Performer.currentEquipment.getEquipedItemByPosition(Imaginarium.items.equip.EquipmentPosition.secondaryHand).posibleStates);
            }
            return dssList;
        }

        //Add question about SpecialState super ultra hitting
        private bool calculateDoesHit() {
            if (Target.isDead())
                return false;
            Random rnd = new Random();
            Stats perfStats = Performer.getFinalStats(), targStats = Target.getFinalStats();
            float initialHitChance = (this.Performer.team.isUser) ? (this.Target.team.isUser ? StatsParameter.PVP_INTIIAL_HIT_CHANCE : StatsParameter.PVE_INTIIAL_HIT_CHANCE) : (StatsParameter.PVE_INTIIAL_HIT_CHANCE);
            float hitChance = MathHelper.Clamp((initialHitChance + perfStats.hit - targStats.dodge) / 100, StatsParameter.MIN_CHANCE_HITTING, StatsParameter.MAX_CHANCE_HITTING);
            return (hitChance - rnd.NextDouble()) > 0;
        }


        public override string ToString()
        {
            string ans = "Attack: \n";
            ans += base.ToString();
            return ans;
        }
    }
}